//
//  WQVideoPreviewViewController.m
//  VideoDemo
//
//  Created by C on 2019/8/19.
//  Copyright © 2019 c. All rights reserved.
//

#import "WQVideoPreviewViewController.h"
#import "WQSysAccessPermission.h"
#import "WQVideoFilePath.h"
#import "WQVideoPlayViewController.h"
//#import "HProgressView.h"
#import "XFCameraButton.h"

#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define SafeViewBottomHeight (kScreenHeight == 812.0 ? 34.0 : 0.0)

#define TIMER_INTERVAL 0.01f                                        // 定时器记录视频间隔
#define VIDEO_RECORDER_MAX_TIME 10.0f                               // 视频最大时长 (单位/秒)
#define VIDEO_RECORDER_MIN_TIME 1.0f                                // 最短视频时长 (单位/秒)
#define START_VIDEO_ANIMATION_DURATION 0.3f                         // 录制视频前的动画时间
#define DEFAULT_VIDEO_ZOOM_FACTOR 3.0f                              // 默认放大倍数

@interface WQVideoPreviewViewController () <AVCaptureFileOutputRecordingDelegate>
{
    CGFloat timeLength;             //时间长度
}

@property (nonatomic,strong) AVCaptureSession *captureSession;
@property (nonatomic,strong) AVCaptureDevice *captureVideoDevice;
@property (nonatomic,strong) AVCaptureDeviceInput *captureVideoInput;
@property (nonatomic,strong) AVCaptureDeviceInput *captureRadioInput;
@property (nonatomic,strong) AVCaptureMovieFileOutput *captureMovieFileOutput;
@property (nonatomic,strong) AVCaptureVideoPreviewLayer *previewLayer;

@property (nonatomic,assign) BOOL isBack;
@property (nonatomic,assign) AVCaptureDevicePosition position;
@property (nonatomic,strong) NSURL *videoUrl;

//提示语
@property (nonatomic,strong) UILabel *tipLabel;
//拍摄按钮
@property (strong, nonatomic) XFCameraButton *cameraButton;
//正在拍摄
@property (assign, nonatomic) Boolean isShooting;
//记录录制时间
@property (nonatomic, strong) NSTimer *timer;
@end

@implementation WQVideoPreviewViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.isBack = YES;
    _isShooting = NO;
    self.cameraButton.progressPercentage = 0.0f;
    
    [WQSysAccessPermission checkVideoCameraAuthorization:^(BOOL isVideoGranted) {
        [WQSysAccessPermission checkAudioAuthorization:^(BOOL isAudioGranted) {
            if (isVideoGranted && isAudioGranted) {
                [self setUpUI];
                [self.captureSession startRunning];
            }
        }];
    }];
   
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.cameraButton setHidden:NO];
    self.cameraButton.progressPercentage = 0.0f;
    
    if (self.captureSession) {
        [self.captureSession startRunning];
    }
    if ([self.shootWay isEqualToString:@"longPress"]) {
        self.tipLabel.text = @"长按拍摄";
        [self tipLabelAnimation];
    } else {
        self.tipLabel.text = @"点击拍摄";
        [self tipLabelAnimation];
    }
    
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [self.captureSession stopRunning];
}

//MARK: - UI
- (void)setUpUI
{
    self.previewLayer.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    [self.view.layer addSublayer:self.previewLayer];
    
    // 设置拍照按钮
    XFCameraButton *recordButton = [XFCameraButton defaultCameraButton];
    CGFloat cameraBtnX = (kScreenWidth - recordButton.bounds.size.width) / 2;
    CGFloat cameraBtnY = kScreenHeight - recordButton.bounds.size.height - 60 - SafeViewBottomHeight;    //距离底部60
    recordButton.frame = CGRectMake(cameraBtnX, cameraBtnY, recordButton.bounds.size.width, recordButton.bounds.size.height);
    [self.view addSubview:recordButton];
    self.cameraButton = recordButton;
    
    // 设置拍照按钮点击事件
    __weak typeof(self) weakSelf = self;
    // 配置拍摄方法
    if ([self.shootWay isEqualToString:@"longPress"]) {
        [recordButton configureLongPressCameraButtonEventWithBlock:^(UILongPressGestureRecognizer *longPressGestureRecognizer) {
            [weakSelf longPressCameraButtonFunc:longPressGestureRecognizer];
        }];
    } else {
        [recordButton configureTapCameraButtonEventWithBlock:^(UITapGestureRecognizer *tapGestureRecognizer) {
            [weakSelf tapCameraButtonFunc:tapGestureRecognizer];
        }];
    }
    
    self.tipLabel = [[UILabel alloc] init];
    self.tipLabel.textColor = [UIColor whiteColor];
    self.tipLabel.textAlignment = NSTextAlignmentCenter;
    self.tipLabel.font = [UIFont systemFontOfSize:13];
    self.tipLabel.bounds = CGRectMake(0, 0, 100, 20);
    self.tipLabel.center = CGPointMake(_cameraButton.center.x, _cameraButton.center.y - 38 - 32);
    [self.view addSubview:self.tipLabel];
    self.tipLabel.alpha = 0;
    
    CALayer *watermarkLayer = [CALayer layer];
    watermarkLayer.bounds = CGRectMake(0, 0, 36, 36);
    watermarkLayer.position = CGPointMake(50, 100);
    UIImage * image = [UIImage imageNamed:@"camera_logo_icon"];
    [watermarkLayer setContents:(__bridge id)image.CGImage];
    [self.view.layer addSublayer:watermarkLayer];
    
    //名字
    CATextLayer *nameLayer = [self textLayerWithTitle:@"qqq" wtihFrame:CGRectMake(66, 82, 200-36 , 36)];
    [self.view.layer addSublayer:nameLayer];
    
    //时间
    CATextLayer *timeLayer = [self textLayerWithTitle:@"2018-09-11 15:12:00" wtihFrame:CGRectMake(66, 97, 200-36 , 36)];
    [self.view.layer addSublayer:timeLayer];
    
    UIButton *backButton = [[UIButton alloc] init];
    backButton.bounds = CGRectMake(0, 0, 40, 40);
    backButton.center = CGPointMake(_cameraButton.center.x - 60 - 40, _cameraButton.center.y);
    [backButton setTitle:@"取消" forState:UIControlStateNormal];
    backButton.titleLabel.font = [UIFont systemFontOfSize:15];
    [backButton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:backButton];
    
    UIButton *switchCameraButton = [[UIButton alloc] initWithFrame:CGRectMake(kScreenWidth-80, 80 + 20, 40, 40)];
    switchCameraButton.bounds = CGRectMake(0, 0, 40, 40);
    switchCameraButton.center = CGPointMake(_cameraButton.center.x + 60 + 40, _cameraButton.center.y);
    [switchCameraButton setImage:[UIImage imageNamed:@"icon_change"] forState:UIControlStateNormal];
    [switchCameraButton addTarget:self action:@selector(switchCamera:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:switchCameraButton];
}

- (CATextLayer *)textLayerWithTitle:(NSString *)title wtihFrame:(CGRect)frame
{
    CATextLayer *nameLayer = [CATextLayer layer];
    nameLayer.string = title;
    nameLayer.foregroundColor = [[UIColor whiteColor] CGColor];
    nameLayer.shadowOpacity = 0.5;
    nameLayer.alignmentMode = kCAAlignmentLeft;
    nameLayer.frame = frame;
    
    //choose a font
    UIFont *titleLayerFont = [UIFont systemFontOfSize:13];
    
    //set layer font
    CFStringRef fontName = (__bridge CFStringRef)titleLayerFont.fontName;
    CGFontRef fontRef = CGFontCreateWithFontName(fontName);
    nameLayer.font = fontRef;
    nameLayer.fontSize = titleLayerFont.pointSize;
    CGFontRelease(fontRef);
    return nameLayer;
}

- (void)back:(UIButton *)sender
{
    [WQVideoFilePath removeVideoPathURL:self.videoUrl];
    [self dismissViewControllerAnimated:YES completion:nil];
}

/**
 *  提示语动画
 */
- (void)tipLabelAnimation
{
    [self.view bringSubviewToFront:self.tipLabel];
    
    __weak typeof(self) weakSelf = self;
    [UIView animateWithDuration:1.0f delay:0.5f options:UIViewAnimationOptionCurveEaseInOut animations:^{
        [weakSelf.tipLabel setAlpha:1];
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1.0f delay:3.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
            [weakSelf.tipLabel setAlpha:0];
        } completion:nil];
    }];
}

//MARK: - 预览准备

/// 视频输入设备
- (AVCaptureDevice *)captureVideoDevice
{
    if (!_captureVideoDevice) {
        //设置默认前置摄像头
        _captureVideoDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
    }
    return _captureVideoDevice;
}

/// 视频输入源
- (AVCaptureDeviceInput *)captureVideoInput
{
    if (!_captureVideoInput) {
        NSError *error;
        _captureVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureVideoDevice error:&error];
        if (error) {
            NSLog(@"获取摄像头失败");
        }
    }
    return _captureVideoInput;
}

/// 音频输入源
- (AVCaptureDeviceInput *)captureRadioInput
{
    if (_captureRadioInput == nil) {
        //音频输入设备
        AVCaptureDevice *captureRadioDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeAudio];
        NSError *error;
        _captureRadioInput = [AVCaptureDeviceInput deviceInputWithDevice:captureRadioDevice error:&error];
        if (error) {
            NSLog(@"获取麦克风失败");
        }
    }
    return _captureRadioInput;
}

/// 输出源设置
- (AVCaptureMovieFileOutput *)captureMovieFileOutput
{
    if(_captureMovieFileOutput == nil)
    {
        _captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
        _captureMovieFileOutput.movieFragmentInterval = kCMTimeInvalid;
    }
    return _captureMovieFileOutput;
}

/// 创建会话
- (AVCaptureSession *)captureSession
{
    if (!_captureSession) {
        _captureSession = [[AVCaptureSession alloc] init];
    
        if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetiFrame960x540])
        {
            //只有高分辨率的视频才是全屏的，如果想要自定义长宽比，就需要先录制高分辨率，再剪裁，如果录制低分辨率，剪裁的区域不好控制
            _captureSession.sessionPreset = AVCaptureSessionPresetiFrame960x540;//画质
        }

        // 1. 连接输入与会话
        if ([_captureSession canAddInput:self.captureVideoInput]) {
            [_captureSession addInput:self.captureVideoInput];
        }
        
        if ([_captureSession canAddInput:self.captureRadioInput]) {
            [_captureSession addInput:self.captureRadioInput];
        }
        
        // 2. 连接输出与会话
        if ([_captureSession canAddOutput:self.captureMovieFileOutput])
        {
            [_captureSession addOutput:self.captureMovieFileOutput];
            //设置防抖,设置录制模式
            AVCaptureConnection *captureConnection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
            if (captureConnection.isVideoStabilizationSupported) {
                captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
            }
        }
    }
    return _captureSession;
}

/// 视频预览层
- (AVCaptureVideoPreviewLayer *)previewLayer
{
    if (!_previewLayer) {
        _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
        _previewLayer.videoGravity = AVLayerVideoGravityResize;//填充模式
    }
    return _previewLayer;
}

//MARK: - Action
//切换摄像头
- (void)switchCamera:(UIButton *)sender
{
    self.isBack = !self.isBack;
    if (self.isBack) {
        //后置
        if (self.captureVideoDevice.position != AVCaptureDevicePositionBack) {
            self.position = AVCaptureDevicePositionBack;
        }
    }
    else {
        //前置
        if (self.captureVideoDevice.position != AVCaptureDevicePositionFront) {
            self.position = AVCaptureDevicePositionFront;
        }
    }
    
    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:self.position];
    if (device) {
        self.captureVideoDevice = device;
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.captureVideoDevice error:nil];
        [self.captureSession beginConfiguration];
        [self.captureSession removeInput:self.captureVideoInput];
        if ([self.captureSession canAddInput:input]) {
            [self.captureSession addInput:input];
            self.captureVideoInput = input;
            [self.captureSession commitConfiguration];
        }
    }
}

//MARK: - 录制
- (BOOL)vertifyAuthStatus
{
    BOOL result = YES;
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)
    {
        result = NO;
    }
    
    //判断用户是否允许访问麦克风权限
    authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)
    {
        result = NO;
    }
    
    return result;
}

// 长按拍摄
- (void)longPressCameraButtonFunc:(UILongPressGestureRecognizer *)sender
{
    if ([self vertifyAuthStatus] == NO) {
        return;
    }
    
    switch (sender.state) {
        case UIGestureRecognizerStateBegan:
        {
            _isShooting = YES;
            [self startVideoRecorder];
            [self.cameraButton startShootAnimationWithDuration:START_VIDEO_ANIMATION_DURATION];
            
            __weak typeof(self) weakSelf = self;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(START_VIDEO_ANIMATION_DURATION * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [weakSelf timerFired];
            });
        }
            break;
        case UIGestureRecognizerStateCancelled:
            [self stopVideoRecorder];
            break;
        case UIGestureRecognizerStateEnded:
            [self stopVideoRecorder];
            break;
        case UIGestureRecognizerStateFailed:
            [self stopVideoRecorder];
            break;
        default:
            break;
    }
    
}

// 点击拍摄
- (void)tapCameraButtonFunc:(UITapGestureRecognizer *)sender
{
    if ([self vertifyAuthStatus] == NO) {
        return;
    }
    
    if (_isShooting == NO) {
        _isShooting = YES;
        [self startVideoRecorder];
        [self.cameraButton startShootAnimationWithDuration:START_VIDEO_ANIMATION_DURATION];
        
        __weak typeof(self) weakSelf = self;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(START_VIDEO_ANIMATION_DURATION * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf timerFired];
        });
    } else {
        [self stopVideoRecorder];
    }
}

/**
 *  开始录制视频
 */
- (void)startVideoRecorder
{
    if (![self.captureSession isRunning]) {
        [self.captureSession startRunning];
    }
    
    self.videoUrl = [WQVideoFilePath getVideoPathURLCache];
    if(self.captureMovieFileOutput.isRecording){
        return;
    }
    [self.captureMovieFileOutput startRecordingToOutputFileURL:self.videoUrl recordingDelegate:self];
}

/**
 *  结束录制视频
 */
- (void)stopVideoRecorder
{
    if (_isShooting)
    {
        _isShooting = NO;
        self.cameraButton.progressPercentage = 0.0f;
        [self.cameraButton stopShootAnimation];
        [self timerStop];
        
        if ([self.captureSession isRunning]) {
            [self.captureSession stopRunning];
        }
        
        if ([self.captureMovieFileOutput isRecording]) {
            [self.captureMovieFileOutput stopRecording];
        }
        
        if (timeLength < VIDEO_RECORDER_MIN_TIME)
        {
            return;
        }
        
        [self.cameraButton setHidden:YES];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            //[weakSelf previewVideoAfterShoot];
            
        });
    }
    else
    {
        // nothing
    }
}

//MARK: - timer

/**
 *  开启定时器
 */
- (void)timerFired
{
    timeLength = 0;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:@selector(timerRecord) userInfo:nil repeats:YES];
}

/**
 *  绿色转圈百分比计算
 */
- (void)timerRecord
{
    if (!_isShooting)
    {
        [self timerStop];
        return ;
    }
    
    // 时间大于VIDEO_RECORDER_MAX_TIME则停止录制
    if (timeLength > self.videoRecorderMaxTime)
    {
        [self stopVideoRecorder];
    }
    
    timeLength += TIMER_INTERVAL;
    
    //    NSLog(@"%lf", timeLength / VIDEO_RECORDER_MAX_TIME);
    
    self.cameraButton.progressPercentage = timeLength / self.videoRecorderMaxTime;
    
}

/**
 *  停止定时器
 */
- (void)timerStop
{
    if ([self.timer isValid])
    {
        [self.timer invalidate];
        self.timer = nil;
    }
}

//MARK: - AVCaptureFileOutputRecordingDelegate:输出代理
//开始录制回调
- (void)captureOutput:(AVCaptureFileOutput *)output didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray<AVCaptureConnection *> *)connections
{
    
}

//录制完成回调
- (void)captureOutput:(AVCaptureFileOutput *)output didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray<AVCaptureConnection *> *)connections error:(nullable NSError *)error
{
    WQVideoPlayViewController *playVideoVC = [[WQVideoPlayViewController alloc] init];
    playVideoVC.fileUrl = self.videoUrl;
    playVideoVC.isOnlyPlay = NO;
    playVideoVC.exportComplete = ^(NSString * _Nonnull path, NSString * _Nonnull fileName) {
        self.exportComplete(path, fileName);
        [self dismissViewControllerAnimated:YES completion:nil];
    };
    [self presentViewController:playVideoVC animated:NO completion:nil];
}

@end
